using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Tilemaps;

[Serializable]
public class ItemData
{
    public TileBase tile;
    public int wegith;
}

// 创建地图的类
public class MapCreate : MonoBehaviour
{
    public Tilemap groundTileMap; // 地面的Tilemap组件
    public TileBase groundTile; // 地面的Tile

    public Tilemap itemTileMap;//植被的Tilemap组件
    public List<ItemData> ItemData;//植被列表

    public Tilemap waterTileMap;//水的Tilemap组件
    public TileBase waterTile; // 水域的Tile

    public int width; // 地图的宽度
    public int height; // 地图的高度

    public int seed; // 生成地图的种子
    public bool useRandomSeed; // 是否使用随机种子

    public float lacunarity; // 柏林噪声的频率

    [Range(0, 1f)]
    public float waterProbability; // 水域的概率




    private float[,] mapData; // 地图数据

    // 创建地图数据
    public void GenerateMap()
    {
        GenerateMapData(); // 生成地图数据
        GenerateTileMap(); // 生成Tile地图
    }

    // 生成地图数据
    private void GenerateMapData()
    {
        // 对于种子的应用
        if (!useRandomSeed) seed = Time.time.GetHashCode(); // 如果不使用随机种子，则使用当前时间的哈希值作为种子
        UnityEngine.Random.InitState(seed); // 初始化随机状态

        float randomOffset = UnityEngine.Random.Range(-10000, 10000); // 随机偏移量
        mapData = new float[width, height]; // 初始化地图数据
        float minValue = float.MaxValue;
        float maxValue = float.MinValue;
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                // 使用柏林噪声生成地图数据
                float noiseValue = Mathf.PerlinNoise(x * lacunarity + randomOffset, y * lacunarity + randomOffset);
                mapData[x, y] = noiseValue;
                if (noiseValue < minValue) minValue = noiseValue;
                if (noiseValue > maxValue) maxValue = noiseValue;
            }
        }
        // 平滑到0~1
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                mapData[x, y] = Mathf.InverseLerp(minValue, maxValue, mapData[x, y]);
            }
        }
    }

    // 生成Tile地图
    private void GenerateTileMap()
    {
        CleanTileMap(); // 清除地图数据

        // 生成地面
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                // 如果则该位置为地面
                TileBase tile = IsGround(x, y) ? groundTile : null;
                groundTileMap.SetTile(new Vector3Int(x, y), tile); // 设置Tile
            }
        }
        CreateItemData();
        CreateWater();
    }

    //填充水
    public void CreateWater()
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                waterTileMap.SetTile(new Vector3Int(x, y), waterTile); // 设置Tile
            }
        }
    }

    //生成植被
    public void CreateItemData()
    {
        // 植被权重和
        int weightTotal = 0;
        for (int i = 0; i < ItemData.Count; i++)
        {
            weightTotal += ItemData[i].wegith;
        }
        //生成植被
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                //只有地面可以生成物品
                if (IsGround(x, y))
                {
                    float randValue = UnityEngine.Random.Range(1, weightTotal + 1);
                    float temp = 0;
                    for (int i = 0; i < ItemData.Count; i++)
                    {
                        temp += ItemData[i].wegith;
                        if (randValue < temp)
                        {
                            // 命中
                            if (ItemData[i].tile) itemTileMap.SetTile(new Vector3Int(x, y), ItemData[i].tile);
                            break;
                        }
                    }
                }

            }
        }
    }

    // 是否在地图范围内
    public bool IsInMapRange(int x, int y)
    {
        return x >= 0 && x < width && y >= 0 && y < height;
    }

    // 是否是地面
    public bool IsGround(int x, int y)
    {
        return mapData[x, y] > waterProbability;
    }

    // 清除地图数据
    public void CleanTileMap()
    {
        groundTileMap.ClearAllTiles(); // 清除所有的Tile
        itemTileMap.ClearAllTiles(); // 清除所有的植被
        waterTileMap.ClearAllTiles(); // 清除所有水
    }
}
